package com.daoshu.socket.handler.netty;

import com.daoshu.socket.config.WebsocketConfig;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.stream.ChunkedWriteHandler;
import io.netty.handler.timeout.IdleStateHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

/**
 * @ClassName: WebSocketInitializer
 * @description: WebSocket解析器
 * @author: Allen
 * @create: 2019-06-14 22:37
 **/
@Component
@Scope("prototype")
public class WebSocketInitializer extends ChannelInitializer<SocketChannel> {

    private static final String HTTP_SERVER_CODEC = "http_server_odec";

    private static final String CHUNKED_WRITE = "chunked_write";

    private static final String HTTP_OBJECT_AGGREGATOR = "http_object_aggregator";

    private static final String PROTOCOL_HANDLER = "protocol_handler";

    private static final String WEB_SOCKET_FRAME = "web_socket_frame";


    @Autowired
    WebsocketConfig nettyConfig;

    @Override
    protected void initChannel(SocketChannel channel) throws Exception {

        ChannelPipeline pipeline = channel.pipeline();


        // HTTP请求的解码和编码
        pipeline.addLast(new IdleStateHandler(nettyConfig.getPingTimeout(),nettyConfig.getPingTimeout(),nettyConfig.getPingTimeout(), TimeUnit.SECONDS));
        pipeline.addLast(HTTP_SERVER_CODEC, new HttpServerCodec());
        // 主要用于处理大数据流，;比如一个1G大小的文件如果你直接传输肯定会撑暴jvm内存的 增加之后就不用考虑这个问题了
        pipeline.addLast(CHUNKED_WRITE, new ChunkedWriteHandler());
        // 把多个消息转换为一个单一的FullHttpRequest或是FullHttpResponse，
        // 原因是HTTP解码器会在每个HTTP消息中生成多个消息对象HttpRequest/HttpResponse,HttpContent,LastHttpContent
        pipeline.addLast(HTTP_OBJECT_AGGREGATOR, new HttpObjectAggregator(65536));
        // WebSocket数据压缩
        pipeline.addLast(PROTOCOL_HANDLER, new WebSocketServerProtocolHandler("/ws"));
        pipeline.addLast(WEB_SOCKET_FRAME, new TextWebSocketFrameHandler(nettyConfig));
    }
}
